package com.nuoniu.sibanyun.service.erp.in.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.bo.UsedGradeRuleBo;
import com.nuoniu.sibanyun.entity.erp.ErpGradeRule;
import com.nuoniu.sibanyun.entity.erp.in.InInventory;
import com.nuoniu.sibanyun.entity.erp.in.InInventoryClass;
import com.nuoniu.sibanyun.mapper.erp.in.InInventoryClassMapper;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpGradeRuleService;
import com.nuoniu.sibanyun.service.erp.in.IInInventoryClassService;
import com.nuoniu.sibanyun.service.erp.in.IInInventoryService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 物料分类 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-09-22
 */
@Service
public class InInventoryClassServiceImpl extends ServiceImpl<InInventoryClassMapper, InInventoryClass> implements IInInventoryClassService {

    @Autowired
    private IErpAccountService erpAccountService;
    @Autowired
    private IErpGradeRuleService erpGradeRuleService;
    @Autowired
    @Lazy
    private IInInventoryService inventoryService;

    @Override
    public List<InInventoryClass> getInventoryClassList() {
        UserInfo userInfo = UserThreadLocal.get();
        InInventoryClass inInventoryClass = new InInventoryClass();
        QueryWrapper<InInventoryClass> queryWrapper = new QueryWrapper<>(inInventoryClass);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        queryWrapper.orderByAsc("class_code");
        return list(queryWrapper);
    }

    public void updateChildrenParentIds(InInventoryClass inInventoryClass, InInventoryClass parentInventoryClass) {
        InInventoryClass inventoryClass = this.getById(inInventoryClass.getId());
        if(inventoryClass.getParentId() != inInventoryClass.getParentId()) {
            String newTreeNames = parentInventoryClass.getTreeNames() + "/" + inInventoryClass.getClassName();
            String newParentIds = parentInventoryClass.getParentIds() + parentInventoryClass.getId() + ",";
            baseMapper.updateChildrenParentIds(inventoryClass.getId(), inventoryClass.getParentIds(), inventoryClass.getTreeNames(),newParentIds, newTreeNames);
            inInventoryClass.setTreeNames(newTreeNames);
            //同步修改物料档案
            //inventoryService.updateInventoryClass(inInventoryClass);
        }
    }

    @Override
    public List<InInventoryClass> getClassByParentId(Long parentId) {
        return baseMapper.getClassByParentId(parentId);
    }

    @Override
    public InInventoryClass getByCode(InInventoryClass inInventoryClass) {
        return baseMapper.getByCode(inInventoryClass);
    }

    @Override
    public InInventoryClass getByName(InInventoryClass inInventoryClass) {
        return baseMapper.getByName(inInventoryClass);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveInventoryClass(InInventoryClass inInventoryClass) {
        List<InInventory> inventoryList = inventoryService.getByClass(inInventoryClass.getParentId());
        if(inventoryList.size() > 0) {
            throw new NuoNiuException("此物料分类已经在物料档案中使用，不可增加下级！");
        }

        UserInfo userInfo = UserThreadLocal.get();
        inInventoryClass.setCompanyId(userInfo.getCompanyId());
        InInventoryClass parentInventoryClass = this.getById(inInventoryClass.getParentId());
        InInventoryClass oldInventoryClass = this.getById(inInventoryClass.getId());
        UsedGradeRuleBo usedGradeRuleBo;
        if(parentInventoryClass != null) { //校验编码规则
            usedGradeRuleBo = erpGradeRuleService.checkCode(inInventoryClass.getClassCode(), parentInventoryClass.getClassCode(), parentInventoryClass.getClassGrade(), "inventoryclass");
        }else {
            usedGradeRuleBo = erpGradeRuleService.checkCode(inInventoryClass.getClassCode(), null, null, "inventoryclass");
        }

        inInventoryClass.setGradeRuleLevel(usedGradeRuleBo.getGradeRuleLevel());
        inInventoryClass.setGradeRuleStr(usedGradeRuleBo.getGradeRuleStr());
        //获取编码规则
        ErpGradeRule erpGradeRuleByCode = erpGradeRuleService.getCurrentYearErpGradeRuleByCode("inventoryclass");
        if(StringUtils.isBlank(erpGradeRuleByCode.getCodingRule())) {
            throw new NuoNiuException("未设置编码级次");
        }

        int length = erpGradeRuleByCode.getCodingRule().length();
        if(parentInventoryClass != null && parentInventoryClass.getClassGrade() >= length) {
            throw new NuoNiuException("已超出编码级次范围");
        }

        InInventoryClass inventoryClass = this.getByCode(inInventoryClass);
        if(inventoryClass != null && (inInventoryClass.getId() == null || !(inventoryClass.getId().equals(inInventoryClass.getId())))) {
            throw new NuoNiuException("编码已存在");
        }

        InInventoryClass inventoryClassByName = this.getByName(inInventoryClass);
        if(inventoryClassByName != null && (inInventoryClass.getId() == null || !(inventoryClassByName.getId().equals(inventoryClassByName.getId())))) {
            throw new NuoNiuException("名称已存在");
        }

        if(inInventoryClass.getId() != null) {
            List<InInventory> inventories = inventoryService.getByClass(inInventoryClass.getId().intValue());
            if(inventories.size() > 0) {
                throw new NuoNiuException("已创建物料档案");
            }

            if(parentInventoryClass != null && (inInventoryClass.getParentId()).equals(parentInventoryClass.getParentId())) {
                throw new NuoNiuException("上级分类不能选择自己");
            }

            //修改下级的父级ids
            if(parentInventoryClass != null) {
                inInventoryClass.setClassGrade(parentInventoryClass.getClassGrade() + 1);
                this.updateChildrenParentIds(inInventoryClass, parentInventoryClass);
                inInventoryClass.setUpdateDate(LocalDateTime.now());
            }else {
                inInventoryClass.setClassGrade(1);
                inInventoryClass.setTreeNames(inInventoryClass.getClassName());
                inInventoryClass.setParentIds("0,");
                InInventoryClass oldClass = this.getById(inInventoryClass.getId());
                String newTreeNames = inInventoryClass.getClassName() + "/";
                String newParentIds = inInventoryClass.getId() + ",";
                baseMapper.updateChildrenParentIds(oldClass.getId(), oldClass.getParentIds(), oldClass.getTreeNames() + "/", newParentIds, newTreeNames);
                //同步修改物料档案
                //inventoryService.updateInventoryClass(inInventoryClass);
            }

            inInventoryClass.setUpdateUserId(userInfo.getUserId());
            inInventoryClass.setUpdateDate(LocalDateTime.now());
        }else {
            if(parentInventoryClass != null) {
                inInventoryClass.setClassGrade(parentInventoryClass.getClassGrade() + 1);
                if (parentInventoryClass.getParentIds().endsWith(",")) {
                    inInventoryClass.setParentIds(parentInventoryClass.getParentIds() + parentInventoryClass.getId() + ",");
                }else {
                    inInventoryClass.setParentIds(parentInventoryClass.getParentIds() + "," + parentInventoryClass.getId() + ",");
                }

                inInventoryClass.setTreeNames(parentInventoryClass.getTreeNames() + "/" + inInventoryClass.getClassName());
                //修改父级
                parentInventoryClass.setClassEnd(false);
                this.updateById(parentInventoryClass);
            }else {
                inInventoryClass.setClassGrade(1);
                inInventoryClass.setTreeNames(inInventoryClass.getClassName());
            }

            inInventoryClass.setCreateUserId(userInfo.getUserId());
            Integer currentAccountId = erpAccountService.getCurrentAccountId();
            inInventoryClass.setAccountId(currentAccountId);
        }

        this.saveOrUpdate(inInventoryClass);

        //判断上级是否末级
        if(oldInventoryClass != null && oldInventoryClass.getParentId() != null) {
            List<InInventoryClass> classes = this.getClassByParentId(oldInventoryClass.getParentId().longValue());
            if(classes.size() == 0) {
                InInventoryClass inClass = new InInventoryClass();
                inClass.setId(oldInventoryClass.getParentId().longValue());
                inClass.setClassEnd(true);
                this.updateById(inClass);
            }
        }
    }

    @Override
    public void deleteById(Integer id, Long parentId) {
        List<InInventory> inventoryList = inventoryService.getByClass(id);
        if(inventoryList.size() > 0) {
            throw new NuoNiuException("该分类下已有物料档案.不能删除");
        }

        InInventoryClass inInventoryClass = this.getById(id);
        if(!inInventoryClass.getClassEnd()) {
            throw new NuoNiuException("只能删除末级");
        }

        this.removeById(id);
        //判断父级是否末级
        if(parentId != null) {
            List<InInventoryClass> inventoryClassList = this.getClassByParentId(parentId);
            if(inventoryClassList.size() == 0) {
                InInventoryClass inventoryClass = new InInventoryClass();
                inventoryClass.setId(parentId);
                inventoryClass.setClassEnd(true);
                this.updateById(inventoryClass);
            }
        }
    }
}
